/*
    Линейная интерполяция
*/

#include <math.h>
#include <stdio.h>
#include <assert.h>
#include "binpol.h"

/* Производящая функция */
double gen_func(const point_t args)
{
    return sin(args.arg_x) * cos(args.arg_y);
}

int main(void)
{
    /* Степень полинома */
    int binpol_degr_x, binpol_degr_y;
    binpol_degr_x = binpol_degr_y = 0;

    /* Границы аргументов */
    point_t args_start, args_end, args;

    /* Получение данных */
    printf("\n Степень полиномов по X и Y: ");
    scanf("%d, %d", &binpol_degr_x, &binpol_degr_y);

    printf("\n Левая граница аргументов производящей функции: ");
    scanf("%lf, %lf", &args_start.arg_x, &args_start.arg_y);

    printf("\n Правая граница аргументов производящей функции: ");
    scanf("%lf, %lf", &args_end.arg_x, &args_end.arg_y);

    do
    {
        printf("\n Значения X и Y: ");
        scanf("%lf, %lf", &args.arg_x, &args.arg_y);

    } while((args.arg_x < args_start.arg_x || args.arg_x > args_end.arg_x) ||
            (args.arg_y < args_start.arg_y || args.arg_y > args_end.arg_y));

    /* Интерполирование */
    binpol_t *binpol_o = binpol_new(binpol_degr_x, binpol_degr_y);
    assert(binpol_o);

    /* Генерирование данных */
    binpol_gen_data(binpol_o, args_start, args_end, gen_func);

    /* Интерполирование */
    double val_poly = binpol_get_val(binpol_o, args);
    double val_real = gen_func(args);
    double fault_pract = val_real - val_poly;

    /* Вывод исходных данных */
    printf("\n%8s\n\n", "X");

    for(int i = 0; i <= binpol_degr_x; i++)
    {
        printf("%8.4lf\n", binpol_o->vals_x[i]);
    }

    printf("\n%8s\n\n", "Y");

    for(int i = 0; i <= binpol_degr_y; i++)
    {
        printf("%8.4lf\n", binpol_o->vals_y[i]);
    }

    printf("\n%8s\n\n", "Z");

    for(int i = 0; i <= binpol_degr_x; i++)
    {
        for(int j = 0; j <= binpol_degr_y; j++)
        {
            printf("%8.4lf\t", binpol_o->vals_z[i][j]);
        }
        printf("\n");
    }

    /* Вывод данных */
    printf("\n Результат: %.4lf", val_poly);
    printf("\n Реальный результат: %.4lf", val_real);
    printf("\n Практическая погрешность: %.4lf\n\n", fault_pract);

    binpol_destroy(binpol_o);

    return 0;
}